package com.zs.games.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.math.BigInteger;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @titel: 字符串帮助类
 * @author: LiChao
 * @dateTime: 2019/7/4 18:12
 * @description:
 **/
public final class StringUtil {
	private static final Logger logger = LoggerFactory.getLogger(StringUtil.class);
	public static String trim(String s) {
		StringBuilder sb = new StringBuilder();
		for (char ch : s.toCharArray()) {
			if (' ' != ch) {
				sb.append(ch);
			}
		}
		s = sb.toString();

		return s.replaceAll("&nbsp;", "").replaceAll(" ", "").replaceAll("　", "").replaceAll("\t", "").replaceAll("\n", "");
	}

	private static final char[] charArray = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
			'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };

	private static final char[] charArrayAll = new char[] { 'a', 'b', 'c', 'd', 'e', 'f','g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
			'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
			'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

	public static String getExt(String filename) {
		return filename.substring(filename.lastIndexOf('.'));
	}

	private static Pattern patternNum = Pattern.compile("[0-9]*");

	private static Pattern patternNickname = Pattern.compile("^[\\s\\S]*$");

	private static Pattern patternUsername = Pattern.compile("^[A-Za-z0-9]*$");

	private static final Pattern PATTERN = Pattern.compile("\\{}");
	public static final String DEFAULT_CHARSET = "UTF-8";

	/**
	 * 数据流转换成字符串（默认编码）
	 * @param in 流数据
	 * @return
	 * @throws Exception
	 */
	public static String readAll(InputStream in) throws Exception {
		BufferedReader reader = new BufferedReader(new InputStreamReader(in, DEFAULT_CHARSET));
		return readAll(reader);
	}
	private static String readAll(BufferedReader reader) {
		try {
			StringBuffer sb = new StringBuffer();
			String ln;
			while (null != (ln = reader.readLine())){
				sb.append(ln);
			}
			return sb.toString();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 校验用户昵称
	 * @param nickName 用户名
	 * @param maxLength 用户名长度上限
	 * @param minLength 用户名长度下限
	 * @throws ImServiceException
	 */
	public static boolean validateNickname(String nickName, Integer maxLength, Integer minLength) {
		if (isNullOrEmpty(nickName)) {
			return false;
		}
		if (nickName.length() > maxLength || nickName.length() < minLength){
			return false;
		}
		Matcher nick = patternNickname.matcher(nickName);
		return nick.matches();
	}

	/**
	 * 校验用户名
	 * @param userName
	 * @param length
	 * @param maxLength
	 * @throws ImServiceException
	 */
	public static boolean validateUsername(String userName,Integer length,Integer maxLength) {
		if (isNullOrEmpty(userName)) {
			return false;
		}
		if (userName.length() < length || userName.length() > maxLength){
			return false;
		}
		Matcher nick = patternUsername.matcher(userName);
		return nick.matches();
	}
	/**
	 * 是否是数字
	 * @param str
	 * @return
	 */
	public static boolean isNumeric(String str){ 
		   Matcher isNum = patternNum.matcher(str);
		   if( !isNum.matches() ){
		       return false; 
		   } 
		   return true; 
	}
	
	
	public static boolean isEmpty(String s) {
		return isNullOrEmpty(s);
	}

	public static boolean isNullOrEmpty(String s) {
		return null == s || 0 == s.trim().length();
	}

	public static boolean isEmpty(Object s) {
		return isNullOrEmpty(s);
	}

	public static boolean isNullOrEmpty(Object s) {
		return null == s || 0 == s.toString().trim().length();
	}

	public static String randomCode() {
		return "" + (new Random().nextInt(899999) + 100000);
	}

	public static String randomPassword() {
		return randomString(6);
	}
	
 	public static String getOutTradeNo() {
		// 产生2个0-9的随机数
		int r1 = new Random().nextInt(10);
		int r2 = new Random().nextInt(10);
		// 一个13位的时间戳
		long now = SystemClock.millisClock().now();
		// 订单ID
		String id = String.valueOf(r1) + String.valueOf(r2) + String.valueOf(now);
		return id;
   	}

	public static String randomString(int length) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int index = new Random().nextInt(36);
			sb.append(charArray[index]);
		}
		return sb.toString();
	}

	public static String randomUUID() {
		UUID uuid = UUID.randomUUID();
		String uuidStr = uuid.toString().replace("-", "");
		return uuidStr;
	}

	public static String getFormatName(String fileName) {
		int index = fileName.lastIndexOf('.');

		return -1 == index ? "jpg" : fileName.substring(index + 1);
	}

	public static String[] getStringList(String str) {
		String sep = ",";
		str = trim(str);
		if (str.endsWith(sep)) {
			str = str.substring(0, str.length() - 1);
		}
		String eSep = ":";
		if (str.indexOf(eSep) >= 0) {
			sep = ":";
		}
		return str.split(sep);
	}

	public static String[] getStringList(String str, String sep) {
		str = trim(str);
		return str.split(sep);
	}

	public static int[] getIntArray(String str, String sep) {
		String[] prop = getStringList(str, sep);
		List<Integer> tmp = new ArrayList<Integer>();
		for (int i = 0; i < prop.length; i++) {
			try {
				int r = Integer.parseInt(prop[i]);
				tmp.add(r);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		int[] ints = new int[tmp.size()];
		for (int i = 0; i < tmp.size(); i++) {
			ints[i] = tmp.get(i);
		}
		return ints;
	}

	public static List<Integer> getIntList(String str, String sep) {
		List<Integer> tmp = new ArrayList<Integer>();
		if (str == null || str.trim().equals("")) {
			return tmp;
		}
		String[] prop = getStringList(str, sep);
		for (int i = 0; i < prop.length; i++) {
			try {
				int r = Integer.parseInt(prop[i]);
				tmp.add(r);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return tmp;
	}

	public static String join(String[] strings, String sep) {
		StringBuffer buffer = new StringBuffer();
		buffer.append(strings[0]);
		for (int i = 1; i < strings.length; i++) {
			buffer.append(sep).append(strings[i]);
		}
		return buffer.toString();
	}

	public static String join(List<Integer> integers, String sep) {
		StringBuffer sb = new StringBuffer();
		sb.append(integers.get(0));
		for (int i = 1; i < integers.size(); i++) {
			sb.append(sep).append(integers.get(i));
		}
		return sb.toString();
	}
	public static String join(String sep,List list) {
		StringBuffer sb = new StringBuffer();
		sb.append(list.get(0));
		for (int i = 1; i < list.size(); i++) {
			sb.append(sep).append(list.get(i));
		}
		return sb.toString();
	}
	public static String getStringByList(List<String> integers, String sep) {
		StringBuffer sb = new StringBuffer();
		sb.append(integers.get(0));
		for (int i = 1; i < integers.size(); i++) {
			sb.append(sep).append(integers.get(i));
		}
		return sb.toString();
	}

	public static double[] getDoubleList(String str) {
		String[] prop = getStringList(str);
		double[] ds = new double[prop.length];
		for (int i = 0; i < ds.length; i++) {
			ds[i] = Double.parseDouble(prop[i]);
		}
		return ds;
	}

	public static List<String> getListBySplit(String str, String split) {
		List<String> list = new ArrayList<String>();
		//|| str.trim().equalsIgnoreCase("")
		if (str == null ) {
			return list;
		}
		String[] strings = str.split(split);
		for (String temp : strings) {
			//&& !temp.trim().equalsIgnoreCase("")
			if (temp != null ) {
				list.add(temp);
			}
		}
		return list;
	}

	public static int[] getIntList(String str) {
		String[] prop = getStringList(str);
		List<Integer> tmp = new ArrayList<>();
		for (int i = 0; i < prop.length; i++) {
			try {
				String sInt = prop[i].trim();
				if (sInt.length() < 20) {
					int r = Integer.parseInt(prop[i].trim());
					tmp.add(r);
				}
			} catch (Exception e) {
			}
		}
		int[] ints = new int[tmp.size()];
		for (int i = 0; i < tmp.size(); i++) {
			ints[i] = tmp.get(i);
		}
		return ints;
	}

	public static String toWrapString(Object obj, String content) {
		if (obj == null) {
			return "null";
		} else {
			return obj.getClass().getName() + "@" + obj.hashCode() + "[\r\n"
					+ content + "\r\n]";
		}
	}

	/**
	 * 将1,2,3和{1,2,3}格式的字符串转化为JDK的bitSet,考虑了两边是否有{}，数字两边是否有空格，是否合法数字
	 */
	public static BitSet bitSetFromString(String str) {
		if (str == null) {
			return new BitSet();
		}
		if (str.startsWith("{")) {
			str = str.substring(1);
		}
		if (str.endsWith("}")) {
			str = str.substring(0, str.length() - 1);
		}
		int[] ints = getIntList(str);
		BitSet bs = new BitSet();
		for (int i : ints) {
			bs.set(i);
		}
		return bs;
	}

	public static boolean hasExcludeChar(String str) {
		if (str != null) {
			char[] chs = str.toCharArray();
			for (int i = 0; i < chs.length; i++) {
				if (Character.getType(chs[i]) == Character.PRIVATE_USE) {
					return true;
				}
			}
		}
		return false;
	}

	public static String replaceSql(String str) {
		if (str != null) {
			return str.replaceAll("'", "’").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;");
		}
		return "";
	}

	/**
	 * 判断两个字符串是否相等
	 * @param s1
	 * @param s2
	 * @return true,字符串相等;false,字符串不相等
	 */
	public static boolean isEquals(String s1, String s2) {
		if (s1 != null) {
			return s1.equals(s2);
		}
		if (s2 != null) {
			return false;
		}
		// 两个字符串都是null
		return true;
	}

	

	/**
	 * 判断字符串是否时数字
	 * @param text
	 * @return
	 */
	public static boolean isDigit(String text) {
		String reg = "[-]*[\\d]+[\\.\\d+]*";
		Pattern pat = Pattern.compile(reg);
		Matcher mat = pat.matcher(text);
		return mat.matches();
	}

	/**
	 * 判断一句话是否是汉语
	 *
	 * @param text
	 * @return
	 */
	public static boolean isChiness(String text) {
		String reg = "[\\w]*[\\u4e00-\\u9fa5]+[\\w]*";
		Pattern pat = Pattern.compile(reg);
		Matcher mat = pat.matcher(text);
		boolean result = mat.matches();
		return result;
	}

	/**
	 * 判断单个字符是否是汉语
	 * @param cha
	 * @return
	 */
	public static boolean isChineseChar(char cha) {
		String reg = "[\\u4e00-\\u9fa5]";
		Pattern pat = Pattern.compile(reg);
		String text = Character.toString(cha);
		Matcher mat = pat.matcher(text);
		boolean result = mat.matches();
		return result;
	}

	/**
	 * 判断字符是否是字母(包括大小写)或者数字
	 *
	 * @param cha
	 * @return
	 */
	public static boolean isLetterAndDigit(String cha) {
		String reg = "[\\w]+";
		Pattern pat = Pattern.compile(reg);
		Matcher mat = pat.matcher(cha);
		boolean result = mat.matches();
		return result;
	}

	/**
	 * 返回字符串中汉字的数量
	 * @param test
	 * @return
	 */
	public static int getChineseCount(String test) {
		int count = 0;
		boolean tempResult = false;
		for (int i = 0; i < test.length(); i++) {
			char cha = test.charAt(i);
			tempResult = isChineseChar(cha);
			if (tempResult) {
				count++;
			}
		}
		return count;
	}

	/**
	 * 返回字符串中字母和数字的个数，其中字母包括大小写
	 *
	 * @param text
	 * @return
	 */
	public static int getLetterAndDigitCount(String text) {
		int count = 0;
		boolean tempResult = false;
		for (int i = 0; i < text.length(); i++) {
			tempResult = isLetterAndDigit(text);
			if (tempResult) {
				count++;
			}
		}
		return count;
	}

	
	/**
	 * 将字符串首字母大写
	 * @param s
	 * @return
	 */
	public static String upperCaseFirstCharOnly(String s) {
		if (s == null || s.length() < 1) {
			return s;
		}
		return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
	}
	  /**
     * 数组转化为String
     * @param s
     * @param sep
     * @return
     */
    public static String arrayToString(String[] s, char sep) {
        if (s == null || s.length == 0){
        	return "";
        }
        StringBuffer buf = new StringBuffer();
        if (s != null) {
            for (int i = 0; i < s.length; i++) {
                if (i > 0) {
					buf.append(sep);
				}
                buf.append(s[i]);
            }
        }
        return buf.toString();
    }
    
	/**
	 * 获取拼起来的key
	 * @param splitString
	 * @param strings
	 * @return
	 */
	public static String getString(String splitString, String... strings){
		StringBuffer stringBuffer = new StringBuffer();
		for(int i = 0; i < strings.length; i++){
			stringBuffer.append(strings[i]);
			if(i == strings.length - 1){
				break;
			}
			stringBuffer.append(splitString);
		}
		return stringBuffer.toString();
	}

    
	/**
	 * 获取拼起来的key
	 * @param splitString
	 * @param strings
	 * @return
	 */
	public static String getString(String splitString, int start, Serializable... strings){
		StringBuffer stringBuffer = new StringBuffer();
		for(int i = start; i < strings.length; i++){
			stringBuffer.append(strings[i]);
			if(i == strings.length - 1){
				break;
			}
			stringBuffer.append(splitString);
		}
		return stringBuffer.toString();
	}

	/**
	 * 首字母转小写
	 * @param s
	 * @return
	 */
	public static String toLowerCaseFirstOne(String s){
		if(Character.isLowerCase(s.charAt(0))) {
			return s;
		} else {
			return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
		}
	}

	public static final String encryptStr(String password) {
		if (password == null) {
			return "";
		} else if (password.length() == 0) {
			return "";
		} else {
			BigInteger bi_passwd = new BigInteger(password.getBytes(Charset.defaultCharset()));
			BigInteger bi_r0 = new BigInteger("01213910847463829232312312");
			BigInteger bi_r1 = bi_r0.xor(bi_passwd);
			return bi_r1.toString(16);
		}
	}

	public static final String decryptStr(String encrypted) {
		if (encrypted == null) {
			return "";
		} else if (encrypted.length() == 0) {
			return "";
		} else {
			BigInteger bi_confuse = new BigInteger("01213910847463829232312312");
			try {
				BigInteger bi_r1 = new BigInteger(encrypted, 16);
				BigInteger bi_r0 = bi_r1.xor(bi_confuse);
				return new String(bi_r0.toByteArray(),Charset.defaultCharset());
			} catch (Exception var4) {
				return "";
			}
		}
	}

	/**
	 * 获取随机浮点数值
	 * @param min
	 * @param max
	 * @return
	 */
	public static Float randomFloat(Float min,Float max){
		Random random = new Random();
		float randomFloat;
		while (true){
			double randomDouble = random.nextDouble() * max * 1000;
			randomFloat = ((int) randomDouble) / 1000f;
			if (randomFloat >= min && randomFloat <= max){
				break;
			}
		}
		DecimalFormat decimalFormat = new DecimalFormat("0.00");
		return Float.valueOf(decimalFormat.format(randomFloat));
	}
	/**
	 * 获取随机整数值
	 * @param min
	 * @param max
	 * @return
	 */
	public static Integer randomInteger(Integer min,Integer max){
		if (min.equals(max)) {
			return min;
		}
		Random random = new Random();
		int randomInteger ;
		while (true){
			randomInteger= random.nextInt() * 100%max ;
			if (randomInteger >= min && randomInteger <= max){
				break;
			}
		}
		return randomInteger;
	}
	public static String randomOneWord(){
		char[] A_z = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
		Random r = new Random();
		int sub = r.nextInt(A_z.length);
		logger.info(String.valueOf(A_z[sub]));
		return String.valueOf(A_z[sub]);
	}
	public static String truncString(String msg, int maxLen, String trailStr) {
		String ret = msg;
		if (msg != null) {
			int len = msg.length();
			int max = maxLen - (trailStr != null ? trailStr.length() : 0);
			if (len > max) {
				logger.info("文本内容超长（长度=" + len + ",但允许的最大长度=" + max + "），内容其余部分将被截断！");
				ret = truncString(msg, max) + (trailStr != null ? trailStr : "");
			}
		}
		return ret;
	}

	public static String truncString(String msg, int maxLen) {
		String ret = msg;
		if (msg != null && msg.length() > maxLen) {
			ret = msg.substring(0, maxLen);
		}
		return ret;
	}

	public static Long[] toLongArray(String str) {
		return toLongArray(",", str);
	}

	public static Long[] toLongArray(String split, String str) {
		if (StringUtil.isEmpty(str)) {
			return new Long[0];
		} else {
			String[] arr = str.split(split);
			Long[] longs = new Long[arr.length];

			for(int i = 0; i < arr.length; ++i) {
				Long v = toLong(arr[i], 0L);
				longs[i] = v;
			}

			return longs;
		}
	}

	public static List<Long> toLongList(String str) {
		return Arrays.asList(toLongArray(str));
	}

	public static List<Long> toLongList(String split, String str) {
		return Arrays.asList(toLongArray(split, str));
	}

	public static long toLong(final Object value, final long defaultValue) {
		return NumberUtil.toLong(String.valueOf(value), defaultValue);
	}

	public static String changeUtf8ToString(String str){
		String S8 = str.replaceAll(" ","");
		String[] S8s = S8.replaceAll("\\\\","%").split("%");
		StringBuffer stringBuffer = new StringBuffer();
		for (int i = 1; i < S8s.length; i++) {
			if (StringUtil.isNumeric(S8s[i])){
				Integer S10 = Integer.valueOf(S8s[i],8);
				stringBuffer.append("%").append(Integer.toHexString(S10));
			}else {
				stringBuffer.append("\\").append(S8s[i]);
			}
		}
		try {
			String string = URLDecoder.decode(stringBuffer.toString(), "UTF-8");
			return string;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String changeStringToUtf8(String str){
		String S16;
		try {
			S16 = URLEncoder.encode(str,"UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return str;
		}
		String[] S16s = S16.split("%");
		StringBuffer stringBuffer = new StringBuffer();
		for (int i = 1; i < S16s.length; i++) {
			Integer S10 = Integer.valueOf(S16s[i],16);
			stringBuffer.append("\\").append(Integer.toOctalString(S10));
		}
		return stringBuffer.toString();
	}

	public static String generateShortUuid(int len) {
		StringBuffer shortBuffer = new StringBuffer();
		String uuid = UUID.randomUUID().toString().replace("-", "");
		for (int i = 0; i < len; i++) {
			String str = uuid.substring(i * 4, i * 4 + 4);
			int x = Integer.parseInt(str, 16);
			shortBuffer.append(charArrayAll[x % 0x3E]);
		}
		return shortBuffer.toString();
	}
	/**
	 * 格式化字符串
	 * 字符串格式："hello, {}"
	 *
	 * @param message
	 * @param args
	 * @return
	 */
	public static String format(String message, Object... args) {
		if (message == null) {
			return null;
		}
		if (args == null || args.length == 0) {
			return message;
		}
		int length = args.length;
		Matcher m = PATTERN.matcher(message);
		StringBuffer sb = new StringBuffer();
		int index = 0;
		Object value;
		while (m.find()) {
			if (index >= length) {
				break;
			}
			value = args[index++];
			if (value == null) {
				m.appendReplacement(sb, "null");
			} else {
				m.appendReplacement(sb, Matcher.quoteReplacement(value.toString()));
			}
		}
		m.appendTail(sb);
		return sb.toString();
	}
}
